"""--------------------------------------------------------------------------------------------------
Filename:   mainframe.py
Author:     Chris Chester (christopher.chester@pg.canterbury.ac.nz), adapted from Ben Han (uha10@uclive.ac.nz)
Date:       27 July 2012
Description:
    GUI layer for the main module of the biofeedback application
    -Partially created using WXGlade
--------------------------------------------------------------------------------------------------"""

import wx
import wx.grid
import frameIcons

ID_EXPORT_PATIENT = 51
ID_VIEW_SESSION = 52
ID_CONFIGURATION = 53
ID_NEW_SESSION = 54
ID_SESSION_START = 3


#===============================================================================
# CLASS: MainFrame(wx.Frame)
#    The GUI front-end for the biofeedback application
#===============================================================================
class MainFrame(wx.Frame):
    """ The main window of the application
    """
    def __init__(self, app, *args, **kwds):
        self.app = app
        self.hdls = app.hdls
        
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        
        # Creating the panels and static boxes to be used in the GUI
        self.panel_main = wx.Panel(self, -1, style=wx.SIMPLE_BORDER|wx.TAB_TRAVERSAL)
        
        self.sizer_top_staticbox = wx.StaticBox(self.panel_main, -1, "Patient record")
        
        self.panel_session = wx.Panel(self.panel_main, -1, style=wx.SUNKEN_BORDER|wx.TAB_TRAVERSAL)
        self.panel_patient = wx.Panel(self.panel_main, -1)
        
        self.sizer_patient_sessions_staticbox = wx.StaticBox(self.panel_patient, -1, "Sessions")
        self.sizer_new_session_staticbox = wx.StaticBox(self.panel_patient, -1, "Start new session")
        
        self.sizer_s01_staticbox = wx.StaticBox(self.panel_session, -1, "Selected session details")
        self.sizer_s02_staticbox = wx.StaticBox(self.panel_session, -1, "Session statistics")
        self.sizer_trials_staticbox = wx.StaticBox(self.panel_session, -1, "Trials")


        self.sizer_p2_staticbox = wx.StaticBox(self.panel_patient, -1, "Additional notes")

         # Naming and setting text boxes and buttons
        self.p_id_text = wx.StaticText(self.panel_patient, -1, "ID:")
        self.p_name_text = wx.StaticText(self.panel_patient, -1, "Name:")
        self.p_dob_text = wx.StaticText(self.panel_patient, -1, "Date of birth:")
        self.p_gender_text = wx.StaticText(self.panel_patient, -1, "Gender:")
        self.p_created_text = wx.StaticText(self.panel_patient, -1, "File created:")
        self.p_id = wx.TextCtrl(self.panel_patient, -1, "")
        self.p_name = wx.TextCtrl(self.panel_patient, -1, "")
        self.p_dob = wx.TextCtrl(self.panel_patient, -1, "")
        self.p_gender = wx.ComboBox(self.panel_patient, -1, choices=["Male", "Female"], style=wx.CB_DROPDOWN|wx.CB_READONLY)
        self.p_created = wx.TextCtrl(self.panel_patient, -1, "", style=wx.TE_READONLY)
        self.p_notes = wx.TextCtrl(self.panel_patient, -1, "<no patient loaded>", style=wx.TE_MULTILINE|wx.TE_LINEWRAP)
        self.p_sessions = wx.grid.Grid(self.panel_patient, -1, size=(1, 1))
        self.button_start_session = wx.Button(self.panel_patient, ID_SESSION_START, "Start Session")
        self.button_view_session = wx.Button(self.panel_patient, ID_VIEW_SESSION, "View session")
        self.s_date_text = wx.StaticText(self.panel_session, -1, "Date:")
        self.s_id_text = wx.StaticText(self.panel_session, -1, "Patient ID:")
        self.s_date = wx.TextCtrl(self.panel_session, -1, "", style=wx.TE_READONLY)
        self.s_id = wx.TextCtrl(self.panel_session, -1, "", style=wx.TE_READONLY)
        self.s_stats = wx.TextCtrl(self.panel_session, -1, "<no session loaded>", style=wx.TE_MULTILINE|wx.TE_READONLY)
        self.s_trials = wx.grid.Grid(self.panel_session, -1, size=(1, 1))

        
        # Menu Bar
        self.menubar = wx.MenuBar()
        self.menu_patient = wx.Menu()
        self.menu_patient_new = wx.MenuItem(self.menu_patient, wx.ID_NEW, "New", "Create a new patient file", wx.ITEM_NORMAL)
        self.menu_patient.AppendItem(self.menu_patient_new)
        self.menu_patient.AppendSeparator()
        self.menu_patient_open = wx.MenuItem(self.menu_patient, wx.ID_OPEN, "Open", "Open an existing patient file", wx.ITEM_NORMAL)
        self.menu_patient.AppendItem(self.menu_patient_open)
        self.menu_patient_save = wx.MenuItem(self.menu_patient, wx.ID_SAVE, "Save as...", "Save the currently displayed patient to file", wx.ITEM_NORMAL)
        self.menu_patient.AppendItem(self.menu_patient_save)
        self.menu_patient.AppendSeparator()
        self.menu_patient_export = wx.MenuItem(self.menu_patient, ID_EXPORT_PATIENT, "Export patient", "Export the patients records to CSV files", wx.ITEM_NORMAL)
        self.menu_patient.AppendItem(self.menu_patient_export)
        self.menu_patient.AppendSeparator()
        self.menu_patient_exit = wx.MenuItem(self.menu_patient, wx.ID_EXIT, "Exit program", "Exit the application", wx.ITEM_NORMAL)
        self.menu_patient.AppendItem(self.menu_patient_exit)
        self.menubar.Append(self.menu_patient, "Patient")
        self.menu_session = wx.Menu()
        menu_session_new = wx.Menu()
        self.menu_start_session = wx.MenuItem(menu_session_new, ID_SESSION_START, "Start a Session", "Start a session", wx.ITEM_NORMAL)
        menu_session_new.AppendItem(self.menu_start_session)
        self.menu_session.AppendMenu(ID_NEW_SESSION, "Start a new session", menu_session_new, "")
        self.menu_session.AppendSeparator()
        self.menu_session_cfg = wx.MenuItem(self.menu_session, ID_CONFIGURATION, "Configuration", "Open the session configuration panel", wx.ITEM_NORMAL)
        self.menu_session.AppendItem(self.menu_session_cfg)
        self.menu_session.AppendSeparator()
        self.menu_session_view = wx.MenuItem(self.menu_session, ID_VIEW_SESSION, "View session", "View the current session in a plot", wx.ITEM_NORMAL)
        self.menu_session.AppendItem(self.menu_session_view)
        self.menubar.Append(self.menu_session, "Session")
        self.menu_help = wx.Menu()
        self.menu_help_about = wx.MenuItem(self.menu_help, wx.ID_ABOUT, "About", "Information about this application", wx.ITEM_NORMAL)
        self.menu_help.AppendItem(self.menu_help_about)
        self.menubar.Append(self.menu_help, "Help")
        self.SetMenuBar(self.menubar)
        # Menu Bar end
        self.statusbar = self.CreateStatusBar(1, 0)
        
        # Tool Bar
        self.main_frame_toolbar = wx.ToolBar(self, -1)
        self.SetToolBar(self.main_frame_toolbar)
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddLabelTool(wx.ID_NEW, "New", frameIcons.getnewBitmap(), wx.NullBitmap, wx.ITEM_NORMAL, "New patient", "Create a new patient file")
        self.main_frame_toolbar.AddLabelTool(wx.ID_OPEN, "Open", frameIcons.getopenBitmap(), wx.NullBitmap, wx.ITEM_NORMAL, "Open patient", "Open an existing patient file")
        self.main_frame_toolbar.AddLabelTool(wx.ID_SAVE, "Save as", frameIcons.getsaveBitmap(), wx.NullBitmap, wx.ITEM_NORMAL, "Save patient", "Save currently loaded patient file")
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddLabelTool(ID_EXPORT_PATIENT, "Export",frameIcons.getexportBitmap(), wx.NullBitmap, wx.ITEM_NORMAL, "Export patient", "Export all the session from the currently loaded patient to CSV files")
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddLabelTool(ID_CONFIGURATION, "Configuration", frameIcons.getconfigureBitmap(), wx.NullBitmap, wx.ITEM_NORMAL, "Configure session options", "Open the configuration window for session options")
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddLabelTool(wx.ID_ABOUT, "About", frameIcons.getinfoBitmap(), wx.NullBitmap, wx.ITEM_NORMAL, "About the application", "Show information dialog about this application")
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddSeparator()
        self.main_frame_toolbar.AddLabelTool(wx.ID_EXIT, "Exit", frameIcons.getexitBitmap(), wx.NullBitmap, wx.ITEM_NORMAL, "Exit the application", "Exit biofeedback application")
        # Tool Bar end
        
       

        
        # Setting events for each element
        self.Bind(wx.EVT_MENU, self.on_new_patient, self.menu_patient_new)
        self.Bind(wx.EVT_MENU, self.on_open_patient, self.menu_patient_open)
        self.Bind(wx.EVT_MENU, self.on_save_patient, self.menu_patient_save)
        self.Bind(wx.EVT_MENU, self.on_export_patient, self.menu_patient_export)
        self.Bind(wx.EVT_MENU, self.on_exit, self.menu_patient_exit)
        self.Bind(wx.EVT_MENU, self.on_new_session, self.menu_start_session)
        self.Bind(wx.EVT_MENU, self.on_config, self.menu_session_cfg)
        self.Bind(wx.EVT_MENU, self.on_view_session, self.menu_session_view)
        self.Bind(wx.EVT_MENU, self.on_about, self.menu_help_about)
        self.Bind(wx.EVT_TOOL, self.on_new_patient, id=wx.ID_NEW)
        self.Bind(wx.EVT_TOOL, self.on_open_patient, id=wx.ID_OPEN)
        self.Bind(wx.EVT_TOOL, self.on_save_patient, id=wx.ID_SAVE)
        self.Bind(wx.EVT_TOOL, self.on_export_patient, id=ID_EXPORT_PATIENT)
        self.Bind(wx.EVT_TOOL, self.on_config, id=ID_CONFIGURATION)
        self.Bind(wx.EVT_TOOL, self.on_about, id=wx.ID_ABOUT)
        self.Bind(wx.EVT_TOOL, self.on_exit, id=wx.ID_EXIT)
        self.Bind(wx.EVT_TEXT, self.on_patient_changed, self.p_id)
        self.Bind(wx.EVT_TEXT, self.on_patient_changed, self.p_name)
        self.Bind(wx.EVT_TEXT, self.on_patient_changed, self.p_dob)
        self.Bind(wx.EVT_TEXT, self.on_patient_changed, self.p_gender)
        self.Bind(wx.EVT_COMBOBOX, self.on_patient_changed, self.p_gender)
        self.Bind(wx.EVT_TEXT, self.on_patient_changed, self.p_created)
        self.Bind(wx.grid.EVT_GRID_CMD_SELECT_CELL, self.on_session_select, self.p_sessions)
        self.Bind(wx.EVT_BUTTON, self.on_new_session, id=ID_SESSION_START)
        self.Bind(wx.EVT_BUTTON, self.on_view_session, id=ID_VIEW_SESSION)
        
        self.Bind(wx.EVT_CLOSE, self.app.on_exit)   # bind handler for window close

        self.__set_properties()
        self.__do_layout()

    def __set_properties(self):
        '''
        Sets the properties for the elements in the GUI
        '''
        
        self.SetTitle("Biofeedback Impedance Monitor Application")
        self.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNFACE))
        self.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.statusbar.SetStatusWidths([-1])
        
        # statusbar fields
        statusbar_fields = ["(Status update are displayed here)"]
        
        for i in range(len(statusbar_fields)):
            self.statusbar.SetStatusText(statusbar_fields[i], i)
            
        self.main_frame_toolbar.SetToolBitmapSize((64, 64))
        self.main_frame_toolbar.Realize()
        
        #Patient related constructs
        self.p_id_text.SetMinSize((100, 20))
        self.p_id_text.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.p_name_text.SetMinSize((100, 20))
        self.p_name_text.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.p_dob_text.SetMinSize((100, 20))
        self.p_dob_text.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.p_gender_text.SetMinSize((100, 20))
        self.p_gender_text.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.p_created_text.SetMinSize((100, 20))
        self.p_created_text.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.p_id.SetMinSize((150, 25))
        self.p_id.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.p_name.SetMinSize((150, 25))
        self.p_name.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.p_dob.SetMinSize((150, 25))
        self.p_dob.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.p_gender.SetMinSize((100, 25))
        self.p_gender.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.p_gender.SetSelection(-1)
        self.p_created.SetMinSize((150, 25))
        self.p_created.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.p_notes.SetFont(wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.p_sessions.CreateGrid(1, 2)
        self.p_sessions.SetRowLabelSize(28)
        self.p_sessions.SetColLabelSize(25)
        self.p_sessions.EnableEditing(0)
        self.p_sessions.SetSelectionMode(wx.grid.Grid.wxGridSelectRows)
        self.p_sessions.SetColLabelValue(0, "Date/Time")
        self.p_sessions.SetColSize(0, 150)
        self.p_sessions.SetColLabelValue(1, "No. of Swallows")
        self.p_sessions.SetColSize(1, 150)
        self.p_sessions.SetMinSize((390, 200))
        self.p_sessions.SetFont(wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, "MS Shell Dlg 2"))
        
        #Button related constructs
        self.button_start_session.SetMinSize((120, 30))
        self.button_start_session.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.button_start_session.SetToolTipString("Start a new session")
        self.button_view_session.SetMinSize((120, 30))
        self.button_view_session.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.button_view_session.SetToolTipString("Start a new skill training session")
        
        #Button related constructs
        self.s_date_text.SetMinSize((80, 20))
        self.s_date_text.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.s_id_text.SetMinSize((80, 20))
        self.s_id_text.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.s_date.SetMinSize((150, 25))
        self.s_date.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, "MS Shell Dlg 2"))
        self.s_id.SetMinSize((150, 25))
        self.s_id.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, "MS Shell Dlg 2"))
        self.s_stats.SetFont(wx.Font(9, wx.MODERN, wx.NORMAL, wx.NORMAL, 0, "Courier New"))
        self.s_trials.CreateGrid(1, 2)
        self.s_trials.SetRowLabelSize(30)
        self.s_trials.SetColLabelSize(25)
        self.s_trials.EnableEditing(0)
        self.s_trials.SetSelectionMode(wx.grid.Grid.wxGridSelectRows)
        self.s_trials.SetColLabelValue(0, "Time Gap")
        self.s_trials.SetColSize(0, 150)
        self.s_trials.SetColLabelValue(1, "Result")
        self.s_trials.SetColSize(1, 150)
        self.s_trials.SetMinSize((300, 50))
        self.s_trials.SetFont(wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, "MS Shell Dlg 2"))
        
        #Panel related constructs
        self.panel_session.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
        self.panel_session.Enable(False)
        self.panel_main.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, "MS Shell Dlg 2"))
        self.panel_main.Enable(False)
              
        self.__enable_patient(False)
        self.__enable_session(False)

    def __do_layout(self):
        '''
        Sets the layout of the WX GUI
        '''
        
        # Create sizers for each of the element boxes
        sizer_frame = wx.BoxSizer(wx.VERTICAL)
        sizer_panel_main = wx.BoxSizer(wx.HORIZONTAL)
        sizer_top = wx.StaticBoxSizer(self.sizer_top_staticbox, wx.VERTICAL)
        sizer_s0 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_s01 = wx.StaticBoxSizer(self.sizer_s01_staticbox, wx.HORIZONTAL)
        sizer_trials = wx.StaticBoxSizer(self.sizer_trials_staticbox, wx.VERTICAL)
        sizer_details = wx.BoxSizer(wx.VERTICAL)
        sizer_s2 = wx.StaticBoxSizer(self.sizer_s02_staticbox, wx.HORIZONTAL)
        sizer_s1 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_s12 = wx.BoxSizer(wx.VERTICAL)
        sizer_s11 = wx.BoxSizer(wx.VERTICAL)
        sizer_patient = wx.BoxSizer(wx.HORIZONTAL)
        sizer_patient_buttons = wx.BoxSizer(wx.VERTICAL)
        sizer_new_session = wx.StaticBoxSizer(self.sizer_new_session_staticbox, wx.VERTICAL)
        sizer_patient_sessions = wx.StaticBoxSizer(self.sizer_patient_sessions_staticbox, wx.VERTICAL)
        sizer_patient_details = wx.BoxSizer(wx.VERTICAL)
        sizer_p2 = wx.StaticBoxSizer(self.sizer_p2_staticbox, wx.HORIZONTAL)
        sizer_p1 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_p12 = wx.BoxSizer(wx.VERTICAL)
        sizer_p11 = wx.BoxSizer(wx.VERTICAL)
        
        #Panel Sizers
        self.SetSizer(sizer_frame)
        self.panel_main.SetSizer(sizer_panel_main)
        self.panel_patient.SetSizer(sizer_patient)
        self.panel_session.SetSizer(sizer_s0)
        
        #Adding elements to each of the boxes
        
        #Patient
        sizer_p11.Add(self.p_id_text, 1, wx.TOP|wx.EXPAND, 5)
        sizer_p11.Add(self.p_name_text, 1, wx.TOP|wx.EXPAND, 5)
        sizer_p11.Add(self.p_dob_text, 1, wx.TOP|wx.EXPAND, 5)
        sizer_p11.Add(self.p_gender_text, 1, wx.TOP|wx.EXPAND, 5)
        sizer_p11.Add(self.p_created_text, 1, wx.TOP|wx.EXPAND, 5)
        sizer_p1.Add(sizer_p11, 1, wx.LEFT|wx.EXPAND, 5)
        sizer_p1.Add(sizer_p12, 2, wx.EXPAND, 0)
        sizer_p12.Add(self.p_id, 1, wx.ALL|wx.EXPAND, 2)
        sizer_p12.Add(self.p_name, 1, wx.ALL|wx.EXPAND, 2)
        sizer_p12.Add(self.p_dob, 1, wx.ALL|wx.EXPAND, 2)
        sizer_p12.Add(self.p_gender, 1, wx.LEFT|wx.RIGHT|wx.TOP, 2)
        sizer_p12.Add(self.p_created, 1, wx.ALL|wx.EXPAND, 2)
        sizer_patient_details.Add(sizer_p1, 0, wx.EXPAND, 0)
        sizer_patient_details.Add(sizer_p2, 1, wx.TOP|wx.EXPAND, 5)
        sizer_p2.Add(self.p_notes, 1, wx.EXPAND, 0)
        sizer_patient_sessions.Add(self.p_sessions, 1, wx.EXPAND, 0)
        sizer_patient.Add(sizer_patient_details, 0, wx.ALL|wx.EXPAND, 5)
        sizer_patient.Add(sizer_patient_sessions, 1, wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.EXPAND, 5)
        sizer_patient.Add(sizer_patient_buttons, 0, wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.EXPAND, 5)
        
        #Sessions
        sizer_new_session.Add(self.button_start_session, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5)
        sizer_patient_buttons.Add(sizer_new_session, 1, wx.EXPAND, 0)
        sizer_patient_buttons.Add(self.button_view_session, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 10)
        sizer_top.Add(self.panel_patient, 1, wx.EXPAND, 0)
        sizer_top.Add(self.panel_session, 1, wx.ALL|wx.EXPAND, 5)
        sizer_s11.Add(self.s_date_text, 1, wx.TOP|wx.EXPAND, 5)
        sizer_s11.Add(self.s_id_text, 1, wx.TOP|wx.EXPAND, 5)
        sizer_s1.Add(sizer_s11, 1, wx.LEFT|wx.EXPAND, 5)
        sizer_s1.Add(sizer_s12, 2, wx.EXPAND, 0)
        sizer_s12.Add(self.s_date, 1, wx.ALL|wx.EXPAND, 2)
        sizer_s12.Add(self.s_id, 1, wx.ALL|wx.EXPAND, 2)
        sizer_details.Add(sizer_s1, 0, wx.EXPAND, 0)
        sizer_details.Add(sizer_s2, 1, wx.TOP|wx.EXPAND, 5)
        sizer_trials.Add(self.s_trials, 1, wx.EXPAND|wx.FIXED_MINSIZE, 3)
        sizer_s2.Add(self.s_stats, 1, wx.EXPAND, 0)
        sizer_s01.Add(sizer_details, 0, wx.EXPAND, 0)
        sizer_s01.Add(sizer_trials, 1, wx.EXPAND, 0)
        sizer_s0.Add(sizer_s01, 4, wx.ALL|wx.EXPAND, 5)

        sizer_panel_main.Add(sizer_top, 1, wx.ALL|wx.EXPAND, 5)
        sizer_frame.Add(self.panel_main, 1, wx.EXPAND, 0)

        sizer_frame.Fit(self)
        self.Layout()
    
        
    def __enable_patient(self, boo):
        # Used to enable/disable controls depending on whether there is a current
        # patient loaded.
        self.panel_main.Enable(boo)
        self.menu_session.Enable(ID_NEW_SESSION, boo)
        self.main_frame_toolbar.EnableTool(wx.ID_SAVE, boo)
        self.main_frame_toolbar.EnableTool(ID_EXPORT_PATIENT, boo)
        self.main_frame_toolbar.EnableTool(ID_CONFIGURATION, boo)
        self.menu_patient.Enable(wx.ID_SAVE, boo)
        self.menu_patient.Enable(ID_EXPORT_PATIENT, boo)
      
    def __connect(self, boo):
        #Used when you connect to the device
        self.button_start_session.Enable(boo) 
      
        
    def __bind_patient(self):
        self.Bind(wx.EVT_TEXT, self.on_patient_changed, self.p_id)
        self.Bind(wx.EVT_TEXT, self.on_patient_changed, self.p_name)
        self.Bind(wx.EVT_TEXT, self.on_patient_changed, self.p_gender)
        self.Bind(wx.EVT_COMBOBOX, self.on_patient_changed, self.p_gender)
        self.Bind(wx.EVT_TEXT, self.on_patient_changed, self.p_created)
        
    def __unbind_patient(self):
        self.Unbind(wx.EVT_TEXT, self.p_id)
        self.Unbind(wx.EVT_TEXT, self.p_name)
        self.Unbind(wx.EVT_TEXT, self.p_dob)
        self.Unbind(wx.EVT_TEXT, self.p_gender)
        self.Unbind(wx.EVT_COMBOBOX, self.p_gender)
        self.Unbind(wx.EVT_TEXT, self.p_created)
        
    def __enable_session(self, boo):
        self.panel_session.Enable(boo)
        self.button_view_session.Enable(boo)
        self.menu_session.Enable(ID_VIEW_SESSION, boo)
        
    def status_message(self, msg):
        self.statusbar.SetStatusText(msg)
        
    def set_patient_attr(self):
        # Set the patient object attributes from the current control values
        if self.app.status.patient == None:
            pass
        else:
            self.app.status.patient.id = self.p_id.GetValue()
            self.app.status.patient.name = self.p_name.GetValue()
            self.app.status.patient.dob = self.p_dob.GetValue()
            self.app.status.patient.gender = self.p_gender.GetValue()
            self.app.status.patient.notes = self.p_notes.GetValue()
        
    def set_session_attr(self):
        # Set the current session's attribute from the values in the GUI
        if self.app.status.session_disp == None:
            pass
        else:
            self.app.status.session_disp.date = self.s_date.GetValue()
            self.app.status.session_disp.patient = self.s_id.GetValue()
            
    def update_patient_panel(self):
        # Update the patient pane of the main window
        if self.app.status.patient == None:
            self.__enable_patient(False)
        else:
                        
            self.__unbind_patient()
            self.p_id.SetValue(self.app.status.patient.id)
            self.p_name.SetValue(self.app.status.patient.name)
            self.p_dob.SetValue(self.app.status.patient.dob)
            self.p_gender.SetValue(self.app.status.patient.gender)
            self.p_notes.SetValue(self.app.status.patient.notes)
            self.p_created.SetValue(self.app.status.patient.date)
            self.__bind_patient()
            
            # Fill sessions grid
            self.p_sessions.ClearGrid()
            rows = self.p_sessions.GetNumberRows()
            self.p_sessions.DeleteRows(0, rows-1)
            nsessions = len(self.app.status.patient.session_record)
            if nsessions > 1:
                self.p_sessions.AppendRows(nsessions-1)
                
            # Populate session list
            for i in range(nsessions):
                s = self.app.status.patient.session_record[i]
                self.p_sessions.SetCellValue(i, 0, str(s.date))
            self.__enable_patient(True)
            
        self.app.status.session_disp = None
        self.update_session_pane()
        self.Refresh()
        
    def update_session_pane(self):
        # Update the session pane of the main window
        if self.app.status.session_disp == None:
            self.s_date.SetValue('(none)')
            self.s_id.SetValue('(none)')
            self.s_stats.SetValue('No session selected')
            self.__enable_session(False)
        else:
            self.s_date.SetValue(self.app.status.session_disp.date)
            self.s_id.SetValue(self.app.status.session_disp.patient)
            # Display session statistics
            self.s_stats.SetValue(repr(self.app.status.session_disp.sess_time))
            # Fill trial grid
            
            self.__enable_session(True)
        self.Refresh()

            
    #Event Handlers
    def on_new_patient(self, event): # wxGlade: MainFrame.<event_handler>
        self.hdls.new_patient(event)

    def on_open_patient(self, event): # wxGlade: MainFrame.<event_handler>
        self.hdls.open_patient(event)
        
    def on_save_patient(self, event): # wxGlade: MainFrame.<event_handler>
        self.hdls.save_patient(event)
        
    def on_config(self, event): # wxGlade: MainFrame.<event_handler>
        self.hdls.config(event)

    def on_exit(self, event): # wxGlade: MainFrame.<event_handler>
        self.hdls.exit(event)

    def on_new_session(self, event): # wxGlade: MainFrame.<event_handler>
        self.hdls.new_session(event)

    def on_about(self, event): # wxGlade: MainFrame.<event_handler>
        self.hdls.about(event)

    def on_patient_changed(self, event): # wxGlade: MainFrame.<event_handler>
        self.hdls.patient_changed(event)

    def on_session_select(self, event): # wxGlade: MainFrame.<event_handler>
        self.hdls.session_select(event)
        event.Skip()

    def on_export_patient(self, event): # wxGlade: MainFrame.<event_handler>
        self.hdls.export_patient(event)

    def on_view_session(self, event): # wxGlade: MainFrame.<event_handler>
        self.hdls.view_session(event)

    def on_save_as_patient(self, event): # wxGlade: MainFrame.<event_handler>
        print "Event handler `on_save_as_patient' not implemented"
        event.Skip()
        
    def on_auto_connect(self, event): # wxGlade: MainFrame.<event_handler>
        self.hdls.auto_connect(event)
                
    def on_manual_connect(self, event): # wxGlade: MainFrame.<event_handler>
        self.hdls.manual_connect(event)
 

# end of class MainFrame
